//
// AnalogClockView.m
//
// Matt Pharr- pharr@cs.yale.edu
//

#import "AnalogClockView.h"
#import "AnalogClockWraps.h"
#import "AnalogClockWraps.c"
#import <appkit/graphics.h>
#import <libc.h>
#import <dpsclient/wraps.h>
#import <time.h>
#import <math.h>
#import <strings.h>
#import <appkit/NXImage.h>
#import <appkit/publicWraps.h>


@implementation AnalogClockView

- fixPosition
{
  if (currentLocation.x + currentSize.width >= bounds.size.width)
    currentLocation.x = bounds.size.width - currentSize.width;
  if (currentLocation.x <= bounds.origin.x)
    currentLocation.x = 0;

  if (currentLocation.y + currentSize.height >= bounds.size.height)
    currentLocation.y = bounds.size.height - currentSize.height;
  if (currentLocation.y <= bounds.origin.y)
    currentLocation.y = 0;

  return self;
}


- bounceIfNeeded
{
  if (currentLocation.x + currentSize.width >= bounds.size.width)
    moveVector.x= (-1) * randBetween(0.5, 1.5);
  if (currentLocation.x <= bounds.origin.x)  // keep it ON the screen
    moveVector.x= randBetween(0.5, 1.5);

  if (currentLocation.y + currentSize.height >= bounds.size.height)
    moveVector.y= (-1) * randBetween(0.5, 1.5);
  if (currentLocation.y <= bounds.origin.y)
    moveVector.y= randBetween(0.5, 1.5);

  return self;
}


- oneStep
{
  time_t tTime;
  struct tm *currentTime;
  NXPoint p={ 0, CLOCK_HEIGHT+24};

  currentLocation.x += moveVector.x;       // move the x and y positions of the image
  currentLocation.y += moveVector.y;       // as indicated by the move vectors
  [self bounceIfNeeded];
  [self fixPosition];

  time(&tTime);
  currentTime= localtime(&tTime);

  if (secs != currentTime->tm_sec) {
    if (mins != currentTime->tm_min) {
      if ([hourMinuteImage lockFocus] == YES) {
	hours= currentTime->tm_hour;
	mins= currentTime->tm_min;
	drawHourMinuteFace(hours % 12, mins, CLOCK_WIDTH, CLOCK_HEIGHT, hasColor);
	[hourMinuteImage unlockFocus];
      }
    }

    secs= currentTime->tm_sec;

    currentLocation.x += moveVector.x;   // move it one more time so it's not so jerky
    currentLocation.y += moveVector.y;   // when the time changes...
    [self bounceIfNeeded];
    [self fixPosition];

    if ([currentImage lockFocus] == YES) {
      [hourMinuteImage composite:NX_COPY toPoint:&p];
      drawSecond(secs, CLOCK_WIDTH, CLOCK_HEIGHT, hasColor);
      [currentImage unlockFocus];
    }
  }

  [currentImage composite:NX_COPY toPoint:&currentLocation];

  usleep((1*1000000)/68);                 // sleep a few vblanks

  return self;
}



- (const char *)windowTitle
{
  return "Analog Clock";
}



- drawSelf:(const NXRect *)rects :(int)rectCount
{
  if (!rects || !rectCount) {
    return self;
  }

  PSsetgray(0);
  NXRectFill(rects);

  return self;
}


- initFrame:(const NXRect *)frameRect
{
  [super initFrame:frameRect];

  currentLocation.x= 400.0;
  currentLocation.y= 400.0;

  moveVector.x= randBetween(0.5, 1.5);
  moveVector.y= randBetween(0.5, 1.5);

  currentSize.width= CLOCK_WIDTH + 24;
  currentSize.height= CLOCK_HEIGHT + 24;

  currentImage= [[NXImage alloc] initSize:&currentSize];
  [currentImage setFlipped:YES];

  hourMinuteImage= [[NXImage alloc] initSize:&currentSize];
  [hourMinuteImage setFlipped:YES];

  secs= -1;    // force it to redraw the bitmap the first time through
  mins= -1;

  if ([Window defaultDepthLimit] == NX_TwoBitGrayDepth) {   // monochrome screen?
    hasColor= 0;
  }
  else hasColor= 1;

  return self;
}

@end
